

 /*
 This file '_selectable' is part of Firebird Integrated Solution 1.0

 Copyright (c) 2015 Lincong

 Contact:  
        Email: lincong1987@gmail.com

        QQ: 159257119
 
 See Usage at http://www.jplatformx.com/firebird

 Create date: 2015-07-14 04:41
 */

 (function ($, undefined) {

     $.widget("ui.selectable", $.ui.mouse, {
         version: "1.9.2",
         options: {
             appendTo: 'body',
             autoRefresh: true,
             distance: 0,
             filter: '*',
             tolerance: 'touch'
         },
         _create: function () {
             var that = this;

             this.element.addClass("ui-selectable");

             this.dragged = false;

             // cache selectee children based on filter
             var selectees;
             this.refresh = function () {
                 selectees = $(that.options.filter, that.element[0]);
                 selectees.addClass("ui-selectee");
                 selectees.each(function () {
                     var $this = $(this);
                     var pos = $this.offset();
                     $.data(this, "selectable-item", {
                         element: this,
                         $element: $this,
                         left: pos.left,
                         top: pos.top,
                         right: pos.left + $this.outerWidth(),
                         bottom: pos.top + $this.outerHeight(),
                         startselected: false,
                         selected: $this.hasClass('ui-selected'),
                         selecting: $this.hasClass('ui-selecting'),
                         unselecting: $this.hasClass('ui-unselecting')
                     });
                 });
             };
             this.refresh();

             this.selectees = selectees.addClass("ui-selectee");

             this._mouseInit();

             this.helper = $("<div class='ui-selectable-helper'></div>");
         },

         _destroy: function () {
             this.selectees
                 .removeClass("ui-selectee")
                 .removeData("selectable-item");
             this.element
                 .removeClass("ui-selectable ui-selectable-disabled");
             this._mouseDestroy();
         },

         _mouseStart: function (event) {
             var that = this;

             this.opos = [event.pageX, event.pageY];

             if (this.options.disabled)
                 return;

             var options = this.options;

             this.selectees = $(options.filter, this.element[0]);

             this._trigger("start", event);

             $(options.appendTo).append(this.helper);
             // position helper (lasso)
             this.helper.css({
                 "left": event.clientX,
                 "top": event.clientY,
                 "width": 0,
                 "height": 0
             });

             if (options.autoRefresh) {
                 this.refresh();
             }

             this.selectees.filter('.ui-selected').each(function () {
                 var selectee = $.data(this, "selectable-item");
                 selectee.startselected = true;
                 if (!event.metaKey && !event.ctrlKey) {
                     selectee.$element.removeClass('ui-selected');
                     selectee.selected = false;
                     selectee.$element.addClass('ui-unselecting');
                     selectee.unselecting = true;
                     // selectable UNSELECTING callback
                     that._trigger("unselecting", event, {
                         unselecting: selectee.element
                     });
                 }
             });

             $(event.target).parents().andSelf().each(function () {
                 var selectee = $.data(this, "selectable-item");
                 if (selectee) {
                     var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
                     selectee.$element
                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
                     selectee.unselecting = !doSelect;
                     selectee.selecting = doSelect;
                     selectee.selected = doSelect;
                     // selectable (UN)SELECTING callback
                     if (doSelect) {
                         that._trigger("selecting", event, {
                             selecting: selectee.element
                         });
                     } else {
                         that._trigger("unselecting", event, {
                             unselecting: selectee.element
                         });
                     }
                     return false;
                 }
             });

         },

         _mouseDrag: function (event) {
             var that = this;
             this.dragged = true;

             if (this.options.disabled)
                 return;

             var options = this.options;

             var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
             if (x1 > x2) {
                 var tmp = x2;
                 x2 = x1;
                 x1 = tmp;
             }
             if (y1 > y2) {
                 var tmp = y2;
                 y2 = y1;
                 y1 = tmp;
             }
             this.helper.css({left: x1, top: y1, width: x2 - x1, height: y2 - y1});

             this.selectees.each(function () {
                 var selectee = $.data(this, "selectable-item");
                 //prevent helper from being selected if appendTo: selectable
                 if (!selectee || selectee.element == that.element[0])
                     return;
                 var hit = false;
                 if (options.tolerance == 'touch') {
                     hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
                 } else if (options.tolerance == 'fit') {
                     hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
                 }

                 if (hit) {
                     // SELECT
                     if (selectee.selected) {
                         selectee.$element.removeClass('ui-selected');
                         selectee.selected = false;
                     }
                     if (selectee.unselecting) {
                         selectee.$element.removeClass('ui-unselecting');
                         selectee.unselecting = false;
                     }
                     if (!selectee.selecting) {
                         selectee.$element.addClass('ui-selecting');
                         selectee.selecting = true;
                         // selectable SELECTING callback
                         that._trigger("selecting", event, {
                             selecting: selectee.element
                         });
                     }
                 } else {
                     // UNSELECT
                     if (selectee.selecting) {
                         if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
                             selectee.$element.removeClass('ui-selecting');
                             selectee.selecting = false;
                             selectee.$element.addClass('ui-selected');
                             selectee.selected = true;
                         } else {
                             selectee.$element.removeClass('ui-selecting');
                             selectee.selecting = false;
                             if (selectee.startselected) {
                                 selectee.$element.addClass('ui-unselecting');
                                 selectee.unselecting = true;
                             }
                             // selectable UNSELECTING callback
                             that._trigger("unselecting", event, {
                                 unselecting: selectee.element
                             });
                         }
                     }
                     if (selectee.selected) {
                         if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
                             selectee.$element.removeClass('ui-selected');
                             selectee.selected = false;

                             selectee.$element.addClass('ui-unselecting');
                             selectee.unselecting = true;
                             // selectable UNSELECTING callback
                             that._trigger("unselecting", event, {
                                 unselecting: selectee.element
                             });
                         }
                     }
                 }
             });

             return false;
         },

         _mouseStop: function (event) {
             var that = this;

             this.dragged = false;

             var options = this.options;

             $('.ui-unselecting', this.element[0]).each(function () {
                 var selectee = $.data(this, "selectable-item");
                 selectee.$element.removeClass('ui-unselecting');
                 selectee.unselecting = false;
                 selectee.startselected = false;
                 that._trigger("unselected", event, {
                     unselected: selectee.element
                 });
             });
             $('.ui-selecting', this.element[0]).each(function () {
                 var selectee = $.data(this, "selectable-item");
                 selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
                 selectee.selecting = false;
                 selectee.selected = true;
                 selectee.startselected = true;
                 that._trigger("selected", event, {
                     selected: selectee.element
                 });
             });
             this._trigger("stop", event);

             this.helper.remove();

             return false;
         }

     });

 })(jQuery);